<?php


namespace App\Models\CacheModel;


use app\common\lib\PushQueue;
use App\Models\Api\BaseCache;
use think\Exception;
use think\Log;
use AstroTool\Cache\CacheManage;

/**
 * 本命预测模型
 * Class NatalReport
 * @package App\Models\CacheModel
 */
class NatalReport extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zl_natal_report';

    protected $cacheModel = 'natal.report';

    public $gidName = [
        'feelings' => '恋爱',
        'dating' => '婚姻',
        'money' => '财富',
        'carrer' => '事业',
        'academic' => '学业',
    ];

    /**
     * 添加用户本命预测数据
     * @param $data
     * @return bool
     * @throws \Exception
     */
    public function SaveData($order_id, $uid, $rid, $data)
    {
        try
        {
            $this->saveAll($data);
        }
        catch (\Exception $e)
        {
            Log::write($order_id . '添加本命预测数据失败：' . $e->getMessage() . '[ ' . $e->getFile() . '：' . $e->getLine() . ' ]', 'error', true);
            return false;
        }
        $key = $uid . ':' . $rid;
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->rmCache();
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->setCacheKeyDetail('details_v2', $key)->rmCache('details_v2');
        return true;
    }

    /**
     * 更新用户本命预测数据
     * @param $uid
     * @param $rid
     * @param $data
     * @param $where
     * @return bool
     * @throws \Exception
     */
    public function UpdateData($uid, $rid, $data, $where)
    {
        try
        {
            $this->where($where)->update($data);
        }
        catch (\Exception $e)
        {
            Log::write(json_encode($where, true) . '更新本命预测数据失败：' . $e->getMessage() . '[ ' . $e->getFile() . '：' . $e->getLine() . ' ]', 'error', true);
            return false;
        }
        $key = $uid . ':' . $rid;
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->rmCache();
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->setCacheKeyDetail('details_v2', $key)->rmCache('details_v2');
        return true;
    }

    /**
     * 本命预测入队加结果数据写入
     * @param int $uid
     * @param int $rid
     * @param array $unlcok_gids 解锁商品
     * @param $order_id
     * @param null $queueDelay 队列等待时长
     * @throws \Exception
     */
    public function SaveQueue($uid, $rid, $unlcok_gids, $order_id, $queueDelay = null)
    {
        $now_time = time();
        $array = [];
        $recode = (new Recode())->getInfoById($rid);
        if ($recode)
        {
            unset($recode['status'], $recode['aid'], $recode['or_day'], $recode['sun'], $recode['moon'], $recode['merc'], $recode['venu'], $recode['mars'], $recode['jupi'], $recode['satu'], $recode['non'], $recode['lili'], $recode['juno'], $recode['asc'], $recode['mc'], $recode['is_read']);
        }
        $recode = json_encode($recode, true);
        $pushSwitch = null;// 推送开关 默认取配置开关

        foreach ($unlcok_gids as $k => $v)
        {
            if (in_array((int)$v, [54, 55, 56, 57, 58], true))
            {
                $pushSwitch = false; // 精简版不推送
                $queueDelay = 0;
            }
            $array[] = [
                'uid' => $uid,
                'rid' => $rid,
                'gid' => $v,
                'order_num' => $order_id,
                'status' => 1,
                'recode_info' => $recode,
                'create_time' => $now_time,
            ];
        }
        $this->SaveData($order_id, $uid, $rid, $array);
        //本命预测入队
        (new PushQueue())->NatalReport($uid, $rid, $unlcok_gids, $order_id, $pushSwitch, $queueDelay);
    }


    /**
     * 获取订单备份档案信息
     * @param string $order_id
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getOrderRecodeBackRecode($order_id)
    {
        return CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('details_back_recode', $order_id)->getDataAndSet(function () use ($order_id)
        {
            try
            {
                return $this
                    ->where(['order_num' => $order_id])
                    ->group('order_num')
                    ->column('recode_info', 'id');
            }
            catch (\Exception $e)
            {
                return [];
            }
        }, [], 'details_back_recode');
    }

    /**
     * 获取用户档案解锁本命预测详情
     * @param $uid
     * @param $rid
     * @return array|bool|mixed
     * @throws \Exception
     */
    public function getNatalReport($uid, $rid)
    {
        $key = $uid . ':' . $rid;
        $data = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->getDataAndSet(function () use ($uid, $rid)
        {
            return $this->getNatalReportByDb($uid, $rid);
        });

        foreach ($data as $gid => $valueStr)
        {
            $data[$gid] = json_decode($valueStr, true);
        }

        return $data;
    }

    /**
     * 通过数据库 获取用户 档案 计算的所有本命预测
     * @param $uid
     * @param $rid
     * @return array
     */
    protected function getNatalReportByDb($uid, $rid)
    {
        try
        {
            $data = $this->where('uid', $uid)->where('rid', $rid)->column('order_num,content,status,recode_info', 'gid');

            foreach ($data as $key => $value)
            {
                $recordInfo = json_decode($value['recode_info'], true);
                $value['name'] = $recordInfo['name'] ?? '';
                $value['content'] = json_decode($value['content'], true);
                unset($value['recode_info']);

                $data[$key] = json_encode($value);
            }
        }
        catch (Exception $e)
        {
            $data = [];
        }
        return $data;
    }

    /**
     * 获取档案当前状态解锁本命报告GIDS
     * @param $uid
     * @param $rid
     * @return array
     * @throws \Exception
     */
    public function getUnlockGids($uid, $rid): array
    {
        $recodeModel = new \App\Models\Api\Recode();
        $recodeInfo = $recodeModel->getRecode(['uid' => $uid, 'id' => $rid]);
        $arr = [
            'msg' => '',
            'gids' => []
        ];
        $natalReportData = $this->getNatalReport2($recodeInfo);
        if (!$natalReportData)
        {
            return $arr;
        }
        $goods = (new Goods())->batchGetInfoByIds(array_keys($natalReportData));

        $gname = [];
        foreach ($natalReportData as $natalReportDatum)
        {
            if (!$natalReportDatum['recode_is_change'])
            {
                $gname[] = $goods[$natalReportDatum['gid']]['name'];
                $arr['gids'][] = $natalReportDatum['gid'];
            }
        }

        if ($gname)
        {
            $arr['msg'] = implode(',', $gname) . '已购买';
        }

        return $arr;
    }

    /**
     * 获取用户档案解锁本命预测详情
     * @param array $recode
     * @param array $field
     * @return array
     * @throws \Exception
     */
    public function getNatalReport2(array $recode, $field = [])
    {
        $recodeUniqueKey1 = "{$recode['type']}:{$recode['year']}:{$recode['month']}:{$recode['day']}:{$recode['hour']}:{$recode['minute']}:{$recode['timezone']}:{$recode['ew']}:{$recode['long_deg']}:{$recode['long_min']}:{$recode['ns']}:{$recode['lat_deg']}:{$recode['lat_min']}:{$recode['is_summer']}";
        $recodeUniqueKey2 = "{$recodeUniqueKey1}:{$recode['live_country']}{$recode['live_province']}{$recode['live_city']}";

        $natalReportData = $this->getNatalReportALL($recode['uid'], $recode['id'], $field);

        foreach ($natalReportData as $gid => $natalReportDatum)
        {
            $recodeUniqueKey = in_array($gid, [39, 54], false) ? $recodeUniqueKey2 : $recodeUniqueKey1;

            if (isset($natalReportDatum[$recodeUniqueKey]))
            {
                $natalReportDatum[$recodeUniqueKey]['recode_is_change'] = false;
                $natalReportData[$gid] = $natalReportDatum[$recodeUniqueKey];
                continue;
            }

            $resData = [];
            foreach ($natalReportDatum as $natalReportDatumItem)
            {
                if (empty($resData))
                {
                    $resData = $natalReportDatumItem;
                } else
                {
                    if ($natalReportDatumItem['id'] > $resData['id'])
                    {
                        $resData = $natalReportDatumItem;
                    }
                }
            }

            $resData['recode_is_change'] = true;

            $natalReportData[$gid] = $resData;
        }

        return $natalReportData;
    }

    public function getOrderNatalReport($uid, $rid, $orderId, $field = [])
    {
        $natalReportData = $this->getNatalReportALL($uid, $rid, $field);

        $resData = [];
        foreach ($natalReportData as $gid => $natalReportDataLists)
        {
            foreach ($natalReportDataLists as $natalReportDetailsItem)
            {
                if ($natalReportDetailsItem['order_num'] === $orderId)
                {
                    $natalReportDetailsItem['recode_is_change'] = false;
                    $resData[$gid] = $natalReportDetailsItem;
                    break;
                }
            }
        }

        return $resData;
    }

    /**
     * 获取用户档案解锁本命预测详情 v2.6.0
     * @param $uid
     * @param $rid
     * @param array $field
     * @return array|bool|mixed
     * @throws \Exception
     */
    public function getNatalReportALL($uid, $rid, $field = [])
    {
        $key = $uid . ':' . $rid;

        $data = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->setCacheKeyDetail('details_v2', $key)->getDataAndSet(function () use ($uid, $rid)
        {
            return $this->getNatalReportByDb2($uid, $rid);
        }, $field, 'details_v2');

        if ($data && $field && is_string($data))
        {
            $data = [current($field) => json_decode($data, true)];
        } else
        {
            foreach ($data as $gid => $valueStr)
            {
                $data[$gid] = json_decode($valueStr, true);
            }
        }

        return $data;
    }

    /**
     * 通过数据库 获取用户 档案 计算的所有本命预测 v2.6.0
     * @param $uid
     * @param $rid
     * @return array
     */
    protected function getNatalReportByDb2($uid, $rid): array
    {
        try
        {
            $data = $this->where('uid', $uid)->where('rid', $rid)->order('id asc')->column('gid,order_num,content,status,recode_info', 'id');

            $resData = [];
            foreach ($data as $key => $value)
            {
                $recode = json_decode($value['recode_info'], true);

                if (in_array($value['gid'], [39, 54], false))
                {   // 恋爱报告
                    $recodeUniqueKey = "{$recode['type']}:{$recode['year']}:{$recode['month']}:{$recode['day']}:{$recode['hour']}:{$recode['minute']}:{$recode['timezone']}:{$recode['ew']}:{$recode['long_deg']}:{$recode['long_min']}:{$recode['ns']}:{$recode['lat_deg']}:{$recode['lat_min']}:{$recode['is_summer']}:{$recode['live_country']}{$recode['live_province']}{$recode['live_city']}";
                } else
                {
                    $recodeUniqueKey = "{$recode['type']}:{$recode['year']}:{$recode['month']}:{$recode['day']}:{$recode['hour']}:{$recode['minute']}:{$recode['timezone']}:{$recode['ew']}:{$recode['long_deg']}:{$recode['long_min']}:{$recode['ns']}:{$recode['lat_deg']}:{$recode['lat_min']}:{$recode['is_summer']}";
                }

                $value['name'] = $recode['name'] ?? '';
                $value['content'] = json_decode($value['content'], true);

                $resData[$value['gid']][$recodeUniqueKey] = $value;
            }

            foreach ($resData as $gid => $resDatum)
            {
                $resData[$gid] = json_encode($resDatum, JSON_UNESCAPED_UNICODE);
            }
        }
        catch (Exception $e)
        {
            $resData = [];
        }

        return $resData;
    }
}
